home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / ruby / 1.8 / set.rb < prev    next >
Text File  |  2008-09-19  |  28KB  |  1,259 lines

  1. #--
  2. # set.rb - defines the Set class
  3. #++
  4. # Copyright (c) 2002-2008 Akinori MUSHA <knu@iDaemons.org>
  5. #
  6. # Documentation by Akinori MUSHA and Gavin Sinclair. 
  7. #
  8. # All rights reserved.  You can redistribute and/or modify it under the same
  9. # terms as Ruby.
  10. #
  11. #   $Id: set.rb 17051 2008-06-09 09:20:43Z knu $
  12. #
  13. # == Overview 
  14. # This library provides the Set class, which deals with a collection
  15. # of unordered values with no duplicates.  It is a hybrid of Array's
  16. # intuitive inter-operation facilities and Hash's fast lookup.  If you
  17. # need to keep values ordered, use the SortedSet class.
  18. #
  19. # The method +to_set+ is added to Enumerable for convenience.
  20. #
  21. # See the Set class for an example of usage.
  22.  
  23.  
  24. #
  25. # Set implements a collection of unordered values with no duplicates.
  26. # This is a hybrid of Array's intuitive inter-operation facilities and
  27. # Hash's fast lookup.
  28. #
  29. # Several methods accept any Enumerable object (implementing +each+)
  30. # for greater flexibility: new, replace, merge, subtract, |, &, -, ^.
  31. #
  32. # The equality of each couple of elements is determined according to
  33. # Object#eql? and Object#hash, since Set uses Hash as storage.
  34. #
  35. # Finally, if you are using class Set, you can also use Enumerable#to_set
  36. # for convenience.
  37. #
  38. # == Example
  39. #
  40. #   require 'set'
  41. #   s1 = Set.new [1, 2]                   # -> #<Set: {1, 2}>
  42. #   s2 = [1, 2].to_set                    # -> #<Set: {1, 2}>
  43. #   s1 == s2                              # -> true
  44. #   s1.add("foo")                         # -> #<Set: {1, 2, "foo"}>
  45. #   s1.merge([2, 6])                      # -> #<Set: {6, 1, 2, "foo"}>
  46. #   s1.subset? s2                         # -> false
  47. #   s2.subset? s1                         # -> true
  48. #
  49. # == Contact
  50. #
  51. #   - Akinori MUSHA <knu@iDaemons.org> (current maintainer)
  52. #
  53. class Set
  54.   include Enumerable
  55.  
  56.   # Creates a new set containing the given objects.
  57.   def self.[](*ary)
  58.     new(ary)
  59.   end
  60.  
  61.   # Creates a new set containing the elements of the given enumerable
  62.   # object.
  63.   #
  64.   # If a block is given, the elements of enum are preprocessed by the
  65.   # given block.
  66.   def initialize(enum = nil, &block) # :yields: o
  67.     @hash ||= Hash.new
  68.  
  69.     enum.nil? and return
  70.  
  71.     if block
  72.       enum.each { |o| add(block[o]) }
  73.     else
  74.       merge(enum)
  75.     end
  76.   end
  77.  
  78.   # Copy internal hash.
  79.   def initialize_copy(orig)
  80.     @hash = orig.instance_eval{@hash}.dup
  81.   end
  82.  
  83.   # Returns the number of elements.
  84.   def size
  85.     @hash.size
  86.   end
  87.   alias length size
  88.  
  89.   # Returns true if the set contains no elements.
  90.   def empty?
  91.     @hash.empty?
  92.   end
  93.  
  94.   # Removes all elements and returns self.
  95.   def clear
  96.     @hash.clear
  97.     self
  98.   end
  99.  
  100.   # Replaces the contents of the set with the contents of the given
  101.   # enumerable object and returns self.
  102.   def replace(enum)
  103.     if enum.class == self.class
  104.       @hash.replace(enum.instance_eval { @hash })
  105.     else
  106.       enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  107.       clear
  108.       enum.each { |o| add(o) }
  109.     end
  110.  
  111.     self
  112.   end
  113.  
  114.   # Converts the set to an array.  The order of elements is uncertain.
  115.   def to_a
  116.     @hash.keys
  117.   end
  118.  
  119.   def flatten_merge(set, seen = Set.new)
  120.     set.each { |e|
  121.       if e.is_a?(Set)
  122.     if seen.include?(e_id = e.object_id)
  123.       raise ArgumentError, "tried to flatten recursive Set"
  124.     end
  125.  
  126.     seen.add(e_id)
  127.     flatten_merge(e, seen)
  128.     seen.delete(e_id)
  129.       else
  130.     add(e)
  131.       end
  132.     }
  133.  
  134.     self
  135.   end
  136.   protected :flatten_merge
  137.  
  138.   # Returns a new set that is a copy of the set, flattening each
  139.   # containing set recursively.
  140.   def flatten
  141.     self.class.new.flatten_merge(self)
  142.   end
  143.  
  144.   # Equivalent to Set#flatten, but replaces the receiver with the
  145.   # result in place.  Returns nil if no modifications were made.
  146.   def flatten!
  147.     if detect { |e| e.is_a?(Set) }
  148.       replace(flatten())
  149.     else
  150.       nil
  151.     end
  152.   end
  153.  
  154.   # Returns true if the set contains the given object.
  155.   def include?(o)
  156.     @hash.include?(o)
  157.   end
  158.   alias member? include?
  159.  
  160.   # Returns true if the set is a superset of the given set.
  161.   def superset?(set)
  162.     set.is_a?(Set) or raise ArgumentError, "value must be a set"
  163.     return false if size < set.size
  164.     set.all? { |o| include?(o) }
  165.   end
  166.  
  167.   # Returns true if the set is a proper superset of the given set.
  168.   def proper_superset?(set)
  169.     set.is_a?(Set) or raise ArgumentError, "value must be a set"
  170.     return false if size <= set.size
  171.     set.all? { |o| include?(o) }
  172.   end
  173.  
  174.   # Returns true if the set is a subset of the given set.
  175.   def subset?(set)
  176.     set.is_a?(Set) or raise ArgumentError, "value must be a set"
  177.     return false if set.size < size
  178.     all? { |o| set.include?(o) }
  179.   end
  180.  
  181.   # Returns true if the set is a proper subset of the given set.
  182.   def proper_subset?(set)
  183.     set.is_a?(Set) or raise ArgumentError, "value must be a set"
  184.     return false if set.size <= size
  185.     all? { |o| set.include?(o) }
  186.   end
  187.  
  188.   # Calls the given block once for each element in the set, passing
  189.   # the element as parameter.  Returns an enumerator if no block is
  190.   # given.
  191.   def each
  192.     block_given? or return enum_for(__method__)
  193.     @hash.each_key { |o| yield(o) }
  194.     self
  195.   end
  196.  
  197.   # Adds the given object to the set and returns self.  Use +merge+ to
  198.   # add several elements at once.
  199.   def add(o)
  200.     @hash[o] = true
  201.     self
  202.   end
  203.   alias << add
  204.  
  205.   # Adds the given object to the set and returns self.  If the
  206.   # object is already in the set, returns nil.
  207.   def add?(o)
  208.     if include?(o)
  209.       nil
  210.     else
  211.       add(o)
  212.     end
  213.   end
  214.  
  215.   # Deletes the given object from the set and returns self.  Use +subtract+ to
  216.   # delete several items at once.
  217.   def delete(o)
  218.     @hash.delete(o)
  219.     self
  220.   end
  221.  
  222.   # Deletes the given object from the set and returns self.  If the
  223.   # object is not in the set, returns nil.
  224.   def delete?(o)
  225.     if include?(o)
  226.       delete(o)
  227.     else
  228.       nil
  229.     end
  230.   end
  231.  
  232.   # Deletes every element of the set for which block evaluates to
  233.   # true, and returns self.
  234.   def delete_if
  235.     to_a.each { |o| @hash.delete(o) if yield(o) }
  236.     self
  237.   end
  238.  
  239.   # Do collect() destructively.
  240.   def collect!
  241.     set = self.class.new
  242.     each { |o| set << yield(o) }
  243.     replace(set)
  244.   end
  245.   alias map! collect!
  246.  
  247.   # Equivalent to Set#delete_if, but returns nil if no changes were
  248.   # made.
  249.   def reject!
  250.     n = size
  251.     delete_if { |o| yield(o) }
  252.     size == n ? nil : self
  253.   end
  254.  
  255.   # Merges the elements of the given enumerable object to the set and
  256.   # returns self.
  257.   def merge(enum)
  258.     if enum.is_a?(Set)
  259.       @hash.update(enum.instance_eval { @hash })
  260.     else
  261.       enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  262.       enum.each { |o| add(o) }
  263.     end
  264.  
  265.     self
  266.   end
  267.  
  268.   # Deletes every element that appears in the given enumerable object
  269.   # and returns self.
  270.   def subtract(enum)
  271.     enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  272.     enum.each { |o| delete(o) }
  273.     self
  274.   end
  275.  
  276.   # Returns a new set built by merging the set and the elements of the
  277.   # given enumerable object.
  278.   def |(enum)
  279.     enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  280.     dup.merge(enum)
  281.   end
  282.   alias + |        ##
  283.   alias union |        ##
  284.  
  285.   # Returns a new set built by duplicating the set, removing every
  286.   # element that appears in the given enumerable object.
  287.   def -(enum)
  288.     enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  289.     dup.subtract(enum)
  290.   end
  291.   alias difference -    ##
  292.  
  293.   # Returns a new set containing elements common to the set and the
  294.   # given enumerable object.
  295.   def &(enum)
  296.     enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  297.     n = self.class.new
  298.     enum.each { |o| n.add(o) if include?(o) }
  299.     n
  300.   end
  301.   alias intersection &    ##
  302.  
  303.   # Returns a new set containing elements exclusive between the set
  304.   # and the given enumerable object.  (set ^ enum) is equivalent to
  305.   # ((set | enum) - (set & enum)).
  306.   def ^(enum)
  307.     enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  308.     n = Set.new(enum)
  309.     each { |o| if n.include?(o) then n.delete(o) else n.add(o) end }
  310.     n
  311.   end
  312.  
  313.   # Returns true if two sets are equal.  The equality of each couple
  314.   # of elements is defined according to Object#eql?.
  315.   def ==(set)
  316.     equal?(set) and return true
  317.  
  318.     set.is_a?(Set) && size == set.size or return false
  319.  
  320.     hash = @hash.dup
  321.     set.all? { |o| hash.include?(o) }
  322.   end
  323.  
  324.   def hash    # :nodoc:
  325.     @hash.hash
  326.   end
  327.  
  328.   def eql?(o)    # :nodoc:
  329.     return false unless o.is_a?(Set)
  330.     @hash.eql?(o.instance_eval{@hash})
  331.   end
  332.  
  333.   # Classifies the set by the return value of the given block and
  334.   # returns a hash of {value => set of elements} pairs.  The block is
  335.   # called once for each element of the set, passing the element as
  336.   # parameter.
  337.   #
  338.   # e.g.:
  339.   #
  340.   #   require 'set'
  341.   #   files = Set.new(Dir.glob("*.rb"))
  342.   #   hash = files.classify { |f| File.mtime(f).year }
  343.   #   p hash    # => {2000=>#<Set: {"a.rb", "b.rb"}>,
  344.   #             #     2001=>#<Set: {"c.rb", "d.rb", "e.rb"}>,
  345.   #             #     2002=>#<Set: {"f.rb"}>}
  346.   def classify # :yields: o
  347.     h = {}
  348.  
  349.     each { |i|
  350.       x = yield(i)
  351.       (h[x] ||= self.class.new).add(i)
  352.     }
  353.  
  354.     h
  355.   end
  356.  
  357.   # Divides the set into a set of subsets according to the commonality
  358.   # defined by the given block.
  359.   #
  360.   # If the arity of the block is 2, elements o1 and o2 are in common
  361.   # if block.call(o1, o2) is true.  Otherwise, elements o1 and o2 are
  362.   # in common if block.call(o1) == block.call(o2).
  363.   #
  364.   # e.g.:
  365.   #
  366.   #   require 'set'
  367.   #   numbers = Set[1, 3, 4, 6, 9, 10, 11]
  368.   #   set = numbers.divide { |i,j| (i - j).abs == 1 }
  369.   #   p set     # => #<Set: {#<Set: {1}>,
  370.   #             #            #<Set: {11, 9, 10}>,
  371.   #             #            #<Set: {3, 4}>,
  372.   #             #            #<Set: {6}>}>
  373.   def divide(&func)
  374.     if func.arity == 2
  375.       require 'tsort'
  376.  
  377.       class << dig = {}        # :nodoc:
  378.     include TSort
  379.  
  380.     alias tsort_each_node each_key
  381.     def tsort_each_child(node, &block)
  382.       fetch(node).each(&block)
  383.     end
  384.       end
  385.  
  386.       each { |u|
  387.     dig[u] = a = []
  388.     each{ |v| func.call(u, v) and a << v }
  389.       }
  390.  
  391.       set = Set.new()
  392.       dig.each_strongly_connected_component { |css|
  393.     set.add(self.class.new(css))
  394.       }
  395.       set
  396.     else
  397.       Set.new(classify(&func).values)
  398.     end
  399.   end
  400.  
  401.   InspectKey = :__inspect_key__         # :nodoc:
  402.  
  403.   # Returns a string containing a human-readable representation of the
  404.   # set. ("#<Set: {element1, element2, ...}>")
  405.   def inspect
  406.     ids = (Thread.current[InspectKey] ||= [])
  407.  
  408.     if ids.include?(object_id)
  409.       return sprintf('#<%s: {...}>', self.class.name)
  410.     end
  411.  
  412.     begin
  413.       ids << object_id
  414.       return sprintf('#<%s: {%s}>', self.class, to_a.inspect[1..-2])
  415.     ensure
  416.       ids.pop
  417.     end
  418.   end
  419.  
  420.   def pretty_print(pp)    # :nodoc:
  421.     pp.text sprintf('#<%s: {', self.class.name)
  422.     pp.nest(1) {
  423.       pp.seplist(self) { |o|
  424.     pp.pp o
  425.       }
  426.     }
  427.     pp.text "}>"
  428.   end
  429.  
  430.   def pretty_print_cycle(pp)    # :nodoc:
  431.     pp.text sprintf('#<%s: {%s}>', self.class.name, empty? ? '' : '...')
  432.   end
  433. end
  434.  
  435. # SortedSet implements a set which elements are sorted in order.  See Set.
  436. class SortedSet < Set
  437.   @@setup = false
  438.  
  439.   class << self
  440.     def [](*ary)    # :nodoc:
  441.       new(ary)
  442.     end
  443.  
  444.     def setup    # :nodoc:
  445.       @@setup and return
  446.  
  447.       module_eval {
  448.         # a hack to shut up warning
  449.         alias old_init initialize
  450.         remove_method :old_init
  451.       }
  452.       begin
  453.     require 'rbtree'
  454.  
  455.     module_eval %{
  456.       def initialize(*args, &block)
  457.         @hash = RBTree.new
  458.         super
  459.       end
  460.     }
  461.       rescue LoadError
  462.     module_eval %{
  463.       def initialize(*args, &block)
  464.         @keys = nil
  465.         super
  466.       end
  467.  
  468.       def clear
  469.         @keys = nil
  470.         super
  471.       end
  472.  
  473.       def replace(enum)
  474.         @keys = nil
  475.         super
  476.       end
  477.  
  478.       def add(o)
  479.         @keys = nil
  480.         @hash[o] = true
  481.         self
  482.       end
  483.       alias << add
  484.  
  485.       def delete(o)
  486.         @keys = nil
  487.         @hash.delete(o)
  488.         self
  489.       end
  490.  
  491.       def delete_if
  492.         n = @hash.size
  493.         super
  494.         @keys = nil if @hash.size != n
  495.         self
  496.       end
  497.  
  498.       def merge(enum)
  499.         @keys = nil
  500.         super
  501.       end
  502.  
  503.       def each
  504.         block_given? or return enum_for(__method__)
  505.         to_a.each { |o| yield(o) }
  506.         self
  507.       end
  508.  
  509.       def to_a
  510.         (@keys = @hash.keys).sort! unless @keys
  511.         @keys
  512.       end
  513.     }
  514.       end
  515.  
  516.       @@setup = true
  517.     end
  518.   end
  519.  
  520.   def initialize(*args, &block)    # :nodoc:
  521.     SortedSet.setup
  522.     initialize(*args, &block)
  523.   end
  524. end
  525.  
  526. module Enumerable
  527.   # Makes a set from the enumerable object with given arguments.
  528.   # Needs to +require "set"+ to use this method.
  529.   def to_set(klass = Set, *args, &block)
  530.     klass.new(self, *args, &block)
  531.   end
  532. end
  533.  
  534. # =begin
  535. # == RestricedSet class
  536. # RestricedSet implements a set with restrictions defined by a given
  537. # block.
  538. # === Super class
  539. #     Set
  540. # === Class Methods
  541. # --- RestricedSet::new(enum = nil) { |o| ... }
  542. # --- RestricedSet::new(enum = nil) { |rset, o| ... }
  543. #     Creates a new restricted set containing the elements of the given
  544. #     enumerable object.  Restrictions are defined by the given block.
  545. #     If the block's arity is 2, it is called with the RestrictedSet
  546. #     itself and an object to see if the object is allowed to be put in
  547. #     the set.
  548. #     Otherwise, the block is called with an object to see if the object
  549. #     is allowed to be put in the set.
  550. # === Instance Methods
  551. # --- restriction_proc
  552. #     Returns the restriction procedure of the set.
  553. # =end
  554. # class RestricedSet < Set
  555. #   def initialize(*args, &block)
  556. #     @proc = block or raise ArgumentError, "missing a block"
  557. #     if @proc.arity == 2
  558. #       instance_eval %{
  559. #     def add(o)
  560. #       @hash[o] = true if @proc.call(self, o)
  561. #       self
  562. #     end
  563. #     alias << add
  564. #     def add?(o)
  565. #       if include?(o) || !@proc.call(self, o)
  566. #         nil
  567. #       else
  568. #         @hash[o] = true
  569. #         self
  570. #       end
  571. #     end
  572. #     def replace(enum)
  573. #       enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  574. #       clear
  575. #       enum.each { |o| add(o) }
  576. #       self
  577. #     end
  578. #     def merge(enum)
  579. #       enum.is_a?(Enumerable) or raise ArgumentError, "value must be enumerable"
  580. #       enum.each { |o| add(o) }
  581. #       self
  582. #     end
  583. #       }
  584. #     else
  585. #       instance_eval %{
  586. #     def add(o)
  587. #         if @proc.call(o)
  588. #         @hash[o] = true 
  589. #         end
  590. #       self
  591. #     end
  592. #     alias << add
  593. #     def add?(o)
  594. #       if include?(o) || !@proc.call(o)
  595. #         nil
  596. #       else
  597. #         @hash[o] = true
  598. #         self
  599. #       end
  600. #     end
  601. #       }
  602. #     end
  603. #     super(*args)
  604. #   end
  605. #   def restriction_proc
  606. #     @proc
  607. #   end
  608. # end
  609.  
  610. if $0 == __FILE__
  611.   eval DATA.read, nil, $0, __LINE__+4
  612. end
  613.  
  614. __END__
  615.  
  616. require 'test/unit'
  617.  
  618. class TC_Set < Test::Unit::TestCase
  619.   def test_aref
  620.     assert_nothing_raised {
  621.       Set[]
  622.       Set[nil]
  623.       Set[1,2,3]
  624.     }
  625.  
  626.     assert_equal(0, Set[].size)
  627.     assert_equal(1, Set[nil].size)
  628.     assert_equal(1, Set[[]].size)
  629.     assert_equal(1, Set[[nil]].size)
  630.  
  631.     set = Set[2,4,6,4]
  632.     assert_equal(Set.new([2,4,6]), set)
  633.   end
  634.  
  635.   def test_s_new
  636.     assert_nothing_raised {
  637.       Set.new()
  638.       Set.new(nil)
  639.       Set.new([])
  640.       Set.new([1,2])
  641.       Set.new('a'..'c')
  642.       Set.new('XYZ')
  643.     }
  644.     assert_raises(ArgumentError) {
  645.       Set.new(false)
  646.     }
  647.     assert_raises(ArgumentError) {
  648.       Set.new(1)
  649.     }
  650.     assert_raises(ArgumentError) {
  651.       Set.new(1,2)
  652.     }
  653.  
  654.     assert_equal(0, Set.new().size)
  655.     assert_equal(0, Set.new(nil).size)
  656.     assert_equal(0, Set.new([]).size)
  657.     assert_equal(1, Set.new([nil]).size)
  658.  
  659.     ary = [2,4,6,4]
  660.     set = Set.new(ary)
  661.     ary.clear
  662.     assert_equal(false, set.empty?)
  663.     assert_equal(3, set.size)
  664.  
  665.     ary = [1,2,3]
  666.  
  667.     s = Set.new(ary) { |o| o * 2 }
  668.     assert_equal([2,4,6], s.sort)
  669.   end
  670.  
  671.   def test_clone
  672.     set1 = Set.new
  673.     set2 = set1.clone
  674.     set1 << 'abc'
  675.     assert_equal(Set.new, set2)
  676.   end
  677.  
  678.   def test_dup
  679.     set1 = Set[1,2]
  680.     set2 = set1.dup
  681.  
  682.     assert_not_same(set1, set2)
  683.  
  684.     assert_equal(set1, set2)
  685.  
  686.     set1.add(3)
  687.  
  688.     assert_not_equal(set1, set2)
  689.   end
  690.  
  691.   def test_size
  692.     assert_equal(0, Set[].size)
  693.     assert_equal(2, Set[1,2].size)
  694.     assert_equal(2, Set[1,2,1].size)
  695.   end
  696.  
  697.   def test_empty?
  698.     assert_equal(true, Set[].empty?)
  699.     assert_equal(false, Set[1, 2].empty?)
  700.   end
  701.  
  702.   def test_clear
  703.     set = Set[1,2]
  704.     ret = set.clear
  705.  
  706.     assert_same(set, ret)
  707.     assert_equal(true, set.empty?)
  708.   end
  709.  
  710.   def test_replace
  711.     set = Set[1,2]
  712.     ret = set.replace('a'..'c')
  713.  
  714.     assert_same(set, ret)
  715.     assert_equal(Set['a','b','c'], set)
  716.   end
  717.  
  718.   def test_to_a
  719.     set = Set[1,2,3,2]
  720.     ary = set.to_a
  721.  
  722.     assert_equal([1,2,3], ary.sort)
  723.   end
  724.  
  725.   def test_flatten
  726.     # test1
  727.     set1 = Set[
  728.       1,
  729.       Set[
  730.     5,
  731.     Set[7,
  732.       Set[0]
  733.     ],
  734.     Set[6,2],
  735.     1
  736.       ],
  737.       3,
  738.       Set[3,4]
  739.     ]
  740.  
  741.     set2 = set1.flatten
  742.     set3 = Set.new(0..7)
  743.  
  744.     assert_not_same(set2, set1)
  745.     assert_equal(set3, set2)
  746.  
  747.     # test2; destructive
  748.     orig_set1 = set1
  749.     set1.flatten!
  750.  
  751.     assert_same(orig_set1, set1)
  752.     assert_equal(set3, set1)
  753.  
  754.     # test3; multiple occurrences of a set in an set
  755.     set1 = Set[1, 2]
  756.     set2 = Set[set1, Set[set1, 4], 3]
  757.  
  758.     assert_nothing_raised {
  759.       set2.flatten!
  760.     }
  761.  
  762.     assert_equal(Set.new(1..4), set2)
  763.  
  764.     # test4; recursion
  765.     set2 = Set[]
  766.     set1 = Set[1, set2]
  767.     set2.add(set1)
  768.  
  769.     assert_raises(ArgumentError) {
  770.       set1.flatten!
  771.     }
  772.  
  773.     # test5; miscellaneous
  774.     empty = Set[]
  775.     set =  Set[Set[empty, "a"],Set[empty, "b"]]
  776.  
  777.     assert_nothing_raised {
  778.       set.flatten
  779.     }
  780.  
  781.     set1 = empty.merge(Set["no_more", set])
  782.  
  783.     assert_nil(Set.new(0..31).flatten!)
  784.  
  785.     x = Set[Set[],Set[1,2]].flatten!
  786.     y = Set[1,2]
  787.  
  788.     assert_equal(x, y)
  789.   end
  790.  
  791.   def test_include?
  792.     set = Set[1,2,3]
  793.  
  794.     assert_equal(true, set.include?(1))
  795.     assert_equal(true, set.include?(2))
  796.     assert_equal(true, set.include?(3))
  797.     assert_equal(false, set.include?(0))
  798.     assert_equal(false, set.include?(nil))
  799.  
  800.     set = Set["1",nil,"2",nil,"0","1",false]
  801.     assert_equal(true, set.include?(nil))
  802.     assert_equal(true, set.include?(false))
  803.     assert_equal(true, set.include?("1"))
  804.     assert_equal(false, set.include?(0))
  805.     assert_equal(false, set.include?(true))
  806.   end
  807.  
  808.   def test_superset?
  809.     set = Set[1,2,3]
  810.  
  811.     assert_raises(ArgumentError) {
  812.       set.superset?()
  813.     }
  814.  
  815.     assert_raises(ArgumentError) {
  816.       set.superset?(2)
  817.     }
  818.  
  819.     assert_raises(ArgumentError) {
  820.       set.superset?([2])
  821.     }
  822.  
  823.     assert_equal(true, set.superset?(Set[]))
  824.     assert_equal(true, set.superset?(Set[1,2]))
  825.     assert_equal(true, set.superset?(Set[1,2,3]))
  826.     assert_equal(false, set.superset?(Set[1,2,3,4]))
  827.     assert_equal(false, set.superset?(Set[1,4]))
  828.  
  829.     assert_equal(true, Set[].superset?(Set[]))
  830.   end
  831.  
  832.   def test_proper_superset?
  833.     set = Set[1,2,3]
  834.  
  835.     assert_raises(ArgumentError) {
  836.       set.proper_superset?()
  837.     }
  838.  
  839.     assert_raises(ArgumentError) {
  840.       set.proper_superset?(2)
  841.     }
  842.  
  843.     assert_raises(ArgumentError) {
  844.       set.proper_superset?([2])
  845.     }
  846.  
  847.     assert_equal(true, set.proper_superset?(Set[]))
  848.     assert_equal(true, set.proper_superset?(Set[1,2]))
  849.     assert_equal(false, set.proper_superset?(Set[1,2,3]))
  850.     assert_equal(false, set.proper_superset?(Set[1,2,3,4]))
  851.     assert_equal(false, set.proper_superset?(Set[1,4]))
  852.  
  853.     assert_equal(false, Set[].proper_superset?(Set[]))
  854.   end
  855.  
  856.   def test_subset?
  857.     set = Set[1,2,3]
  858.  
  859.     assert_raises(ArgumentError) {
  860.       set.subset?()
  861.     }
  862.  
  863.     assert_raises(ArgumentError) {
  864.       set.subset?(2)
  865.     }
  866.  
  867.     assert_raises(ArgumentError) {
  868.       set.subset?([2])
  869.     }
  870.  
  871.     assert_equal(true, set.subset?(Set[1,2,3,4]))
  872.     assert_equal(true, set.subset?(Set[1,2,3]))
  873.     assert_equal(false, set.subset?(Set[1,2]))
  874.     assert_equal(false, set.subset?(Set[]))
  875.  
  876.     assert_equal(true, Set[].subset?(Set[1]))
  877.     assert_equal(true, Set[].subset?(Set[]))
  878.   end
  879.  
  880.   def test_proper_subset?
  881.     set = Set[1,2,3]
  882.  
  883.     assert_raises(ArgumentError) {
  884.       set.proper_subset?()
  885.     }
  886.  
  887.     assert_raises(ArgumentError) {
  888.       set.proper_subset?(2)
  889.     }
  890.  
  891.     assert_raises(ArgumentError) {
  892.       set.proper_subset?([2])
  893.     }
  894.  
  895.     assert_equal(true, set.proper_subset?(Set[1,2,3,4]))
  896.     assert_equal(false, set.proper_subset?(Set[1,2,3]))
  897.     assert_equal(false, set.proper_subset?(Set[1,2]))
  898.     assert_equal(false, set.proper_subset?(Set[]))
  899.  
  900.     assert_equal(false, Set[].proper_subset?(Set[]))
  901.   end
  902.  
  903.   def test_each
  904.     ary = [1,3,5,7,10,20]
  905.     set = Set.new(ary)
  906.  
  907.     ret = set.each { |o| }
  908.     assert_same(set, ret)
  909.  
  910.     e = set.each
  911.     assert_instance_of(Enumerable::Enumerator, e)
  912.  
  913.     assert_nothing_raised {
  914.       set.each { |o|
  915.     ary.delete(o) or raise "unexpected element: #{o}"
  916.       }
  917.  
  918.       ary.empty? or raise "forgotten elements: #{ary.join(', ')}"
  919.     }
  920.   end
  921.  
  922.   def test_add
  923.     set = Set[1,2,3]
  924.  
  925.     ret = set.add(2)
  926.     assert_same(set, ret)
  927.     assert_equal(Set[1,2,3], set)
  928.  
  929.     ret = set.add?(2)
  930.     assert_nil(ret)
  931.     assert_equal(Set[1,2,3], set)
  932.  
  933.     ret = set.add(4)
  934.     assert_same(set, ret)
  935.     assert_equal(Set[1,2,3,4], set)
  936.  
  937.     ret = set.add?(5)
  938.     assert_same(set, ret)
  939.     assert_equal(Set[1,2,3,4,5], set)
  940.   end
  941.  
  942.   def test_delete
  943.     set = Set[1,2,3]
  944.  
  945.     ret = set.delete(4)
  946.     assert_same(set, ret)
  947.     assert_equal(Set[1,2,3], set)
  948.  
  949.     ret = set.delete?(4)
  950.     assert_nil(ret)
  951.     assert_equal(Set[1,2,3], set)
  952.  
  953.     ret = set.delete(2)
  954.     assert_equal(set, ret)
  955.     assert_equal(Set[1,3], set)
  956.  
  957.     ret = set.delete?(1)
  958.     assert_equal(set, ret)
  959.     assert_equal(Set[3], set)
  960.   end
  961.  
  962.   def test_delete_if
  963.     set = Set.new(1..10)
  964.     ret = set.delete_if { |i| i > 10 }
  965.     assert_same(set, ret)
  966.     assert_equal(Set.new(1..10), set)
  967.  
  968.     set = Set.new(1..10)
  969.     ret = set.delete_if { |i| i % 3 == 0 }
  970.     assert_same(set, ret)
  971.     assert_equal(Set[1,2,4,5,7,8,10], set)
  972.   end
  973.  
  974.   def test_collect!
  975.     set = Set[1,2,3,'a','b','c',-1..1,2..4]
  976.  
  977.     ret = set.collect! { |i|
  978.       case i
  979.       when Numeric
  980.     i * 2
  981.       when String
  982.     i.upcase
  983.       else
  984.     nil
  985.       end
  986.     }
  987.  
  988.     assert_same(set, ret)
  989.     assert_equal(Set[2,4,6,'A','B','C',nil], set)
  990.   end
  991.  
  992.   def test_reject!
  993.     set = Set.new(1..10)
  994.  
  995.     ret = set.reject! { |i| i > 10 }
  996.     assert_nil(ret)
  997.     assert_equal(Set.new(1..10), set)
  998.  
  999.     ret = set.reject! { |i| i % 3 == 0 }
  1000.     assert_same(set, ret)
  1001.     assert_equal(Set[1,2,4,5,7,8,10], set)
  1002.   end
  1003.  
  1004.   def test_merge
  1005.     set = Set[1,2,3]
  1006.  
  1007.     ret = set.merge([2,4,6])
  1008.     assert_same(set, ret)
  1009.     assert_equal(Set[1,2,3,4,6], set)
  1010.   end
  1011.  
  1012.   def test_subtract
  1013.     set = Set[1,2,3]
  1014.  
  1015.     ret = set.subtract([2,4,6])
  1016.     assert_same(set, ret)
  1017.     assert_equal(Set[1,3], set)
  1018.   end
  1019.  
  1020.   def test_plus
  1021.     set = Set[1,2,3]
  1022.  
  1023.     ret = set + [2,4,6]
  1024.     assert_not_same(set, ret)
  1025.     assert_equal(Set[1,2,3,4,6], ret)
  1026.   end
  1027.  
  1028.   def test_minus
  1029.     set = Set[1,2,3]
  1030.  
  1031.     ret = set - [2,4,6]
  1032.     assert_not_same(set, ret)
  1033.     assert_equal(Set[1,3], ret)
  1034.   end
  1035.  
  1036.   def test_and
  1037.     set = Set[1,2,3,4]
  1038.  
  1039.     ret = set & [2,4,6]
  1040.     assert_not_same(set, ret)
  1041.     assert_equal(Set[2,4], ret)
  1042.   end
  1043.  
  1044.   def test_xor
  1045.     set = Set[1,2,3,4]
  1046.     ret = set ^ [2,4,5,5]
  1047.     assert_not_same(set, ret)
  1048.     assert_equal(Set[1,3,5], ret)
  1049.   end
  1050.  
  1051.   def test_eq
  1052.     set1 = Set[2,3,1]
  1053.     set2 = Set[1,2,3]
  1054.  
  1055.     assert_equal(set1, set1)
  1056.     assert_equal(set1, set2)
  1057.     assert_not_equal(Set[1], [1])
  1058.  
  1059.     set1 = Class.new(Set)["a", "b"]
  1060.     set2 = Set["a", "b", set1]
  1061.     set1 = set1.add(set1.clone)
  1062.  
  1063. #    assert_equal(set1, set2)
  1064. #    assert_equal(set2, set1)
  1065.     assert_equal(set2, set2.clone)
  1066.     assert_equal(set1.clone, set1)
  1067.  
  1068.     assert_not_equal(Set[Exception.new,nil], Set[Exception.new,Exception.new], "[ruby-dev:26127]")
  1069.   end
  1070.  
  1071.   # def test_hash
  1072.   # end
  1073.  
  1074.   # def test_eql?
  1075.   # end
  1076.  
  1077.   def test_classify
  1078.     set = Set.new(1..10)
  1079.     ret = set.classify { |i| i % 3 }
  1080.  
  1081.     assert_equal(3, ret.size)
  1082.     assert_instance_of(Hash, ret)
  1083.     ret.each_value { |value| assert_instance_of(Set, value) }
  1084.     assert_equal(Set[3,6,9], ret[0])
  1085.     assert_equal(Set[1,4,7,10], ret[1])
  1086.     assert_equal(Set[2,5,8], ret[2])
  1087.   end
  1088.  
  1089.   def test_divide
  1090.     set = Set.new(1..10)
  1091.     ret = set.divide { |i| i % 3 }
  1092.  
  1093.     assert_equal(3, ret.size)
  1094.     n = 0
  1095.     ret.each { |s| n += s.size }
  1096.     assert_equal(set.size, n)
  1097.     assert_equal(set, ret.flatten)
  1098.  
  1099.     set = Set[7,10,5,11,1,3,4,9,0]
  1100.     ret = set.divide { |a,b| (a - b).abs == 1 }
  1101.  
  1102.     assert_equal(4, ret.size)
  1103.     n = 0
  1104.     ret.each { |s| n += s.size }
  1105.     assert_equal(set.size, n)
  1106.     assert_equal(set, ret.flatten)
  1107.     ret.each { |s|
  1108.       if s.include?(0)
  1109.     assert_equal(Set[0,1], s)
  1110.       elsif s.include?(3)
  1111.     assert_equal(Set[3,4,5], s)
  1112.       elsif s.include?(7)
  1113.     assert_equal(Set[7], s)
  1114.       elsif s.include?(9)
  1115.     assert_equal(Set[9,10,11], s)
  1116.       else
  1117.     raise "unexpected group: #{s.inspect}"
  1118.       end
  1119.     }
  1120.   end
  1121.  
  1122.   def test_inspect
  1123.     set1 = Set[1]
  1124.  
  1125.     assert_equal('#<Set: {1}>', set1.inspect)
  1126.  
  1127.     set2 = Set[Set[0], 1, 2, set1]
  1128.     assert_equal(false, set2.inspect.include?('#<Set: {...}>'))
  1129.  
  1130.     set1.add(set2)
  1131.     assert_equal(true, set1.inspect.include?('#<Set: {...}>'))
  1132.   end
  1133.  
  1134.   # def test_pretty_print
  1135.   # end
  1136.  
  1137.   # def test_pretty_print_cycle
  1138.   # end
  1139. end
  1140.  
  1141. class TC_SortedSet < Test::Unit::TestCase
  1142.   def test_sortedset
  1143.     s = SortedSet[4,5,3,1,2]
  1144.  
  1145.     assert_equal([1,2,3,4,5], s.to_a)
  1146.  
  1147.     prev = nil
  1148.     s.each { |o| assert(prev < o) if prev; prev = o }
  1149.     assert_not_nil(prev)
  1150.  
  1151.     s.map! { |o| -2 * o }
  1152.  
  1153.     assert_equal([-10,-8,-6,-4,-2], s.to_a)
  1154.  
  1155.     prev = nil
  1156.     ret = s.each { |o| assert(prev < o) if prev; prev = o }
  1157.     assert_not_nil(prev)
  1158.     assert_same(s, ret)
  1159.  
  1160.     s = SortedSet.new([2,1,3]) { |o| o * -2 }
  1161.     assert_equal([-6,-4,-2], s.to_a)
  1162.  
  1163.     s = SortedSet.new(['one', 'two', 'three', 'four'])
  1164.     a = []
  1165.     ret = s.delete_if { |o| a << o; o.start_with?('t') }
  1166.     assert_same(s, ret)
  1167.     assert_equal(['four', 'one'], s.to_a)
  1168.     assert_equal(['four', 'one', 'three', 'two'], a)
  1169.  
  1170.     s = SortedSet.new(['one', 'two', 'three', 'four'])
  1171.     a = []
  1172.     ret = s.reject! { |o| a << o; o.start_with?('t') }
  1173.     assert_same(s, ret)
  1174.     assert_equal(['four', 'one'], s.to_a)
  1175.     assert_equal(['four', 'one', 'three', 'two'], a)
  1176.  
  1177.     s = SortedSet.new(['one', 'two', 'three', 'four'])
  1178.     a = []
  1179.     ret = s.reject! { |o| a << o; false }
  1180.     assert_same(nil, ret)
  1181.     assert_equal(['four', 'one', 'three', 'two'], s.to_a)
  1182.     assert_equal(['four', 'one', 'three', 'two'], a)
  1183.   end
  1184. end
  1185.  
  1186. class TC_Enumerable < Test::Unit::TestCase
  1187.   def test_to_set
  1188.     ary = [2,5,4,3,2,1,3]
  1189.  
  1190.     set = ary.to_set
  1191.     assert_instance_of(Set, set)
  1192.     assert_equal([1,2,3,4,5], set.sort)
  1193.  
  1194.     set = ary.to_set { |o| o * -2 }
  1195.     assert_instance_of(Set, set)
  1196.     assert_equal([-10,-8,-6,-4,-2], set.sort)
  1197.  
  1198.     set = ary.to_set(SortedSet)
  1199.     assert_instance_of(SortedSet, set)
  1200.     assert_equal([1,2,3,4,5], set.to_a)
  1201.  
  1202.     set = ary.to_set(SortedSet) { |o| o * -2 }
  1203.     assert_instance_of(SortedSet, set)
  1204.     assert_equal([-10,-8,-6,-4,-2], set.sort)
  1205.   end
  1206. end
  1207.  
  1208. # class TC_RestricedSet < Test::Unit::TestCase
  1209. #   def test_s_new
  1210. #     assert_raises(ArgumentError) { RestricedSet.new }
  1211. #     s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
  1212. #     assert_equal([2,3], s.sort)
  1213. #   end
  1214. #   def test_restriction_proc
  1215. #     s = RestricedSet.new([-1,2,3]) { |o| o > 0 }
  1216. #     f = s.restriction_proc
  1217. #     assert_instance_of(Proc, f)
  1218. #     assert(f[1])
  1219. #     assert(!f[0])
  1220. #   end
  1221. #   def test_replace
  1222. #     s = RestricedSet.new(-3..3) { |o| o > 0 }
  1223. #     assert_equal([1,2,3], s.sort)
  1224. #     s.replace([-2,0,3,4,5])
  1225. #     assert_equal([3,4,5], s.sort)
  1226. #   end
  1227. #   def test_merge
  1228. #     s = RestricedSet.new { |o| o > 0 }
  1229. #     s.merge(-5..5)
  1230. #     assert_equal([1,2,3,4,5], s.sort)
  1231. #     s.merge([10,-10,-8,8])
  1232. #     assert_equal([1,2,3,4,5,8,10], s.sort)
  1233. #   end
  1234. # end
  1235.